package cn.tedu.luban.settle.webapi.service.impl;

import cn.tedu.luban.account.service.IAccountService;
import cn.tedu.luban.commons.enums.settle.SettleStatusEnum;
import cn.tedu.luban.commons.enums.settle.SettleTypeEnum;
import cn.tedu.luban.commons.pojo.account.dto.PaymentDTO;
import cn.tedu.luban.commons.pojo.order.dto.OrderMqDTO;
import cn.tedu.luban.commons.pojo.settle.dto.SettleBillDTO;
import cn.tedu.luban.commons.pojo.settle.model.SettleBill;
import cn.tedu.luban.settle.service.ISettleBillService;
import cn.tedu.luban.settle.service.ISettleEventService;
import cn.tedu.luban.settle.webapi.mapper.SettleMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.parameters.P;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

@Service
@Slf4j
public class SettleBillServiceImpl implements ISettleBillService {

    @Autowired
    private SettleMapper settleMapper;

    @Autowired
    private ISettleEventService settleEventService;

    @DubboReference
    private IAccountService dubboAccountService;


    @Override
    @Transactional
    public void settle(OrderMqDTO settleDTO) {
        log.info("settle方法执行");
        // 先按orderNo去数据库查询settle信息
        List<SettleBill> settleBills=settleMapper.
                getSettleBillByOrderNo(settleDTO.getOrderNo());
        // 如果没有结算记录可以结算
        if(settleBills.size()==0){
            // 商家支付的金额要根据分润比例分别结算给师傅和平台
            List<SettleBillDTO> settleBillDTOs=buildSettleBillParam(settleDTO);
            // 声明对应数据库表泛型类型的集合
            List<SettleBill> settleBillList=new ArrayList<>();
            // 遍历settleBillDTOs将对象转换为SettleBill类型,以完成数据库新增
            for(SettleBillDTO settleBillDTO: settleBillDTOs){
                SettleBill settleBill=new SettleBill();
                BeanUtils.copyProperties(settleBillDTO,settleBill);
//                settleBill.setWorkerId(settleDTO.getUserId());
//                settleBill.setWorkerName(settleDTO.getWorkerName()==null?
//                                            "代用名":settleDTO.getWorkerName());
//                settleBill.setWorkerPhone(settleDTO.getWorkerPhone()==null?
//                                            "13011010110":settleDTO.getWorkerPhone());
                settleBill.setRequestOrderPrice(settleBillDTO.getRequestOrderRawPrice());
                settleBill.setGmtCreate(System.currentTimeMillis());
                settleBill.setGmtModified(System.currentTimeMillis());
                settleBill.setCreateUserId(99L);
                settleBill.setModifiedUserId(99L);
                settleBill.setCreateUserName("mock1");
                settleBill.setModifiedUserName("mock1");
                settleBillList.add(settleBill);
                log.info("即将新增的结算信息为:{}",settleBill);
            }
            // 执行批量新增结算信息到settle表中的操作
            settleMapper.batchInsert(settleBillList);
            // RocketMQ发送消息,执行后续操作
            settleEventService.sendSettledEvent(settleDTO);


        }

    }

    private List<SettleBillDTO> buildSettleBillParam(OrderMqDTO settleDTO) {
        // 返回值是一个List,泛型是SettleBillDTO
        // 这个返回值应该包含两个元素,一个是平台的结算信息,一个是师傅的
        // 针对不一样的信息进行一些处理
        // 获取师傅应得的金额
        Long requestOrderPrice=settleDTO.getRequestOrderPrice();
        // 获取商家提供金额
        Long requestOrderRawPrice=settleDTO.getRequestOrderRawPrice();
        // 创建工人结算信息对象
        SettleBillDTO workerSettleBillDTO=buildSettleBillParam(
                settleDTO,
                requestOrderPrice,
                SettleTypeEnum.SETTLE_TYPE_WORKER.getStatus(),
                settleDTO.getWorkerId());
        // 创建平台结算信息对象
        SettleBillDTO platformSettleBillDTO=buildSettleBillParam(
                settleDTO,
                // 简单计算方法,直接100-80
                // requestOrderRawPrice-requestOrderPrice,
                getPlatformAmount(requestOrderRawPrice,requestOrderPrice),
                SettleTypeEnum.SETTLE_TYPE_PLATFORM.getStatus(),
                999L);
        List<SettleBillDTO> settleBillDTOs=new ArrayList<>();
        settleBillDTOs.add(workerSettleBillDTO);
        settleBillDTOs.add(platformSettleBillDTO);
        return settleBillDTOs;

    }

    private Long getPlatformAmount(Long rawPrice, Long workerPrice) {
        return new BigDecimal(rawPrice).subtract(new BigDecimal(workerPrice)).longValue();
    }

    private SettleBillDTO buildSettleBillParam(OrderMqDTO settleDTO, Long amount, Integer type, Long userId) {
        SettleBillDTO settleBillDTO = new SettleBillDTO();
        BeanUtils.copyProperties(settleDTO,settleBillDTO);
        settleBillDTO.setAmount(amount);
        settleBillDTO.setType(type);
        settleBillDTO.setUserId(userId);
        settleBillDTO.setScale(settleDTO.getProfitScale());
        settleBillDTO.setRequestUserId(settleDTO.getUserId());
        settleBillDTO.setRequestUserName(settleDTO.getUserName());
        settleBillDTO.setRequestUserPhone(settleDTO.getUserPhone());
        settleBillDTO.setStatus(SettleStatusEnum.SETTLE_STATUS_WAIT.getStatus());
        settleBillDTO.setOrderGmtCreate(settleDTO.getGmtCreate());
        settleBillDTO.setTotalAmount(amount);
        return settleBillDTO;
    }

    @Override
    public void mockPayAndUpdateSettleBillStatus(OrderMqDTO orderMqDTO) {
        // 要更新当前用户的余额信息
        PaymentDTO paymentDTO=new PaymentDTO();
        paymentDTO.setUserId(orderMqDTO.getUserId());
        paymentDTO.setOrderNo(orderMqDTO.getOrderNo());
        paymentDTO.setTotalAmount(orderMqDTO.getRequestOrderPrice());
        log.info("模拟支持信息:{}",paymentDTO);
        Long result = dubboAccountService.mockPayment(paymentDTO);
        // result是受影响的行数,大于0才进行后续操作
        if(result > 0){
            // 进行结算状态的修改
            SettleBill settleBill = new SettleBill();
            settleBill.setOrderNo(orderMqDTO.getOrderNo());
            // 将结算状态右新增时赋值的0(未生效),修改为现在的1(已结算)
            settleBill.setStatus(SettleStatusEnum.SETTLE_STATUS_STEELED.getStatus());
            settleBill.setPaymentTime(System.currentTimeMillis());
            settleBill.setGmtModified(System.currentTimeMillis());
            settleBill.setModifiedUserId(99L);
            settleBill.setModifiedUserName("mock1");
            settleMapper.updateStatus(settleBill);
        }else{
            log.warn("{}  账户修改余额失败",paymentDTO);
        }
    }
}
